/* RemoteClassLoader.js
 *
 * Copyright 2006, Tim Dwelle.
 *
 * Licensed under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied.  See
 * the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

$package("dowry.loader");

/**
 * RemoteClassLoader extends the dynamic classloader to
 * perform dynamic classloading from the server, via a DWR
 * call.
 *
 */
$class("RemoteClassLoader").$extends("ClassLoader").$as(
{
    /**
     * The stub for the DWR remote service providing the
     * <code>loadJs()</code> method
     *
     */
    _dwrService : null,

    /**
     * Creates a new classloader instance.
     *
     * @param parentClassLoader  the parent classloader
     *
     * @param dwrService         the stub for the DWR remote
     *                           service providing the
     *                           <code>loadJs()</code>
     *                           method
     *
     */
    RemoteClassLoader : function(parentClassLoader, dwrService)
    {
        this.$super(arguments);
        this._dwrService = dwrService;
    },

    /**
     * Finds the class with the specified fully-qualfiied
     * class name, by dynamically loading the class from
     * the server, via a DWR call.
     *
     * @param className   the fully-qualified class name to
     *                    load
     *
     * @return            the class; or null, if not found
     *
     */
    _findClass : function(className)
    {
        var c = null;

        if (className)
        {
            var url = null;
            if (this._dwrService &&
                this._dwrService._path)
            {
                url = this._dwrService._path + "/dowry/loadJs/" +
                      className.split(".").join("/") + ".js";
            }

            var js = this._loadJs(className);
            c = this._parseClassDefinition(className, js, url);
        }

        return c;
    },

    /**
     * Load the remote class definition via a call to the
     * DWR remote service's <code>loadJs()</code> method.
     * Usually, it is recommended to use asychronous calls
     * with DWR; but in the case of resource loading, we
     * unfortunately must wait for those resources to be
     * loaded before we can continue.
     *
     * @param className   the fully-qualified class name to
     *                    load
     *
     * @return            the raw Javascript containing the
     *                    class definition, as a string
     *
     */
    _loadJs : function(className)
    {
        var js = null;

        if (this._dwrService)
        {
            var meta = { async: false,
                         method: DWREngine.XMLHttpRequest,
                         callback: function(val){ meta.returnValue=val;} };

            this._dwrService.loadJs(className, meta);

            js = meta.returnValue;
            meta = null;
        }

        return js;
    }
});